package com.lf.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lf.constant.ConstantsValue;
import com.lf.constant.ThreadPoolsConstants;
import com.lf.entity.*;
import com.lf.entity.CheckRecordEntity;
import com.lf.entity.vo.front.CheckRecordVo;
import com.lf.entity.vo.front.ReportVo;
import com.lf.entity.vo.front.UserVo;
import com.lf.enums.ErrorCodeEnum;
import com.lf.enums.ExamineStatusEnum;
import com.lf.exception.ApiException;
import com.lf.mapper.*;
import com.lf.service.IUserService;
import com.lf.sms.tencent.SendSms;
import com.lf.util.*;
import com.lf.weixinOriginPay.sdk.MyConfig;
import com.lf.weixinOriginPay.sdk.WXPay;
import com.lf.weixinOriginPay.sdk.WXPayUtil;
import com.lf.weixinOriginPay.value.StaticValue;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;
import tk.mybatis.mapper.entity.Example;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.*;
import java.util.concurrent.*;

/**
 * @Description:
 * @Param:
 * @return:
 * @Author: GXL
 * @Date: 2019/12/05
 */
@Slf4j
@Service
public class UserServiceImpl extends MapperList implements IUserService {


    private ResponseWrapper registerUser(String jscode, Long pid){
        Map<String,String> data = new HashMap<>();
        data.put("appid", redisService.getString(ConstantsValue.WX_COFIG + "WX_APPID"));
        data.put("secret", redisService.getString(ConstantsValue.WX_COFIG + "WX_SECRET"));
        data.put("js_code", jscode);
        data.put("grant_type", ConstantsValue.GRANT_TYPE);
        String s = HttpUtils.sendPost(ConstantsValue.WX_GET_OPENID, data);
        JSONObject json = JSONObject.parseObject(s);
        String openId = json.getString("openid");

        UserEntity user = new UserEntity();
        user.setOpenId(openId);
        user = userMapper.selectOne(user);

        UserVo userVo = new UserVo();


        Map<String, Object> clamis = new HashMap<>();
        if (user != null){
            if (pid != 0 && pid != null && user.getParentId() == null){
                UserEntity parentEntity = new UserEntity();
                parentEntity.setUserId(Integer.valueOf(pid.toString()));
                int pc = userMapper.selectCount(parentEntity);
                if (pc >= 1){
                    user.setParentId(Integer.valueOf(pid.toString()));
                    userMapper.updateByPrimaryKey(user);
                }
            }

            clamis.put("userid", user.getUserId());
            String token = tokenManager.createToken(user.getUserId(), String.valueOf(user.getUserId()), clamis).getToken();

            userVo.setUserId(user.getUserId());
            userVo.setOpenId(user.getOpenId());
            userVo.setToken(token);
            return ResponseWrapper.succeed(userVo);
        }

        String initName = "匿名用户";
        user = new UserEntity();
        user.setOpenId(openId);
        user.setRealName(initName);
        user.setUserName(initName);
        user.setStatus(ConstantsValue.STATUS_NO_DEL);
        user.setBlack(ConstantsValue.STATUS_NO_BLACK);
        user.setAuthStatus(ConstantsValue.NO_AUTH);
        user.setPayStatus(ConstantsValue.STATUS_NO_PAY);
        user.setIsAgent(ConstantsValue.STATUS_NO_AGENT);
        user.setNoDrawn(ConstantsValue.STATUS_DRAWN);
        user.setVisitCode(RandomStringUtils.randomAlphanumeric(15));
        user.setTotalRevenue("0");
        user.setDrawn("0");
        user.setUndrawn("0");

        if (pid != 0 && pid != null && user.getParentId() == null){
            UserEntity parentEntity = new UserEntity();
            parentEntity.setUserId(Integer.valueOf(pid.toString()));
            int pc = userMapper.selectCount(parentEntity);
            if (pc >= 1){
                user.setParentId(Integer.valueOf(pid.toString()));
            }
        }

        userMapper.insert(user);
        Integer userid = user.getUserId();

        clamis.put("userid", userid);
        String token = tokenManager.createToken(user.getUserId(), String.valueOf(user.getUserId()), clamis).getToken();


        /**生成二维码start*/
        final long uid = userid;
        ThreadPoolsConstants.qrCodeThreadPool.execute(new Runnable() {
            @Override
            public void run() {
//                String shareUrl = "https://mp.kxkj.site/littlefish/miniprogram/jump?pid=PID";
                String qrCode = ImageUtils.getIstance().ONLYQR_BASE64(ConstantsValue.SHARE_URL.replace("PID",String.valueOf(uid)));

//                String filepath = "/usr/local/nginx/html/mp/qrcode/UID.jpg";
                try {
                    BASE64Decoder decoder = new sun.misc.BASE64Decoder();
                    byte[] bytes1 = decoder.decodeBuffer(qrCode);
                    ByteArrayInputStream bais = new ByteArrayInputStream(bytes1);
                    BufferedImage bi1 = ImageIO.read(bais);
                    File f1 = new File(ConstantsValue.FILE_PATH.replace("UID",String.valueOf(uid)));
                    ImageIO.write(bi1, "jpg", f1);
//                    filepath = ConstantsValue.NET_PATH.replace("UID",String.valueOf(uid));
                } catch (IOException e) {
                    e.printStackTrace();
                }

                UserQrCode userQrCode = new UserQrCode();
                userQrCode.setQrCode(ConstantsValue.NET_PATH.replace("UID",String.valueOf(uid)));
                userQrCode.setUserId(uid);
                userQrCodeMapper.insert(userQrCode);//更新一下二维码图片 完成注册操作
            }
        });
        /**生成二维码end*/

        userVo.setUserId(userid);
        userVo.setOpenId(openId);
        userVo.setToken(token);

        ReportEntity reportEntity = new ReportEntity();
        reportEntity.setReportUserName("小编说");
        reportEntity.setBeReportUserId(userid);
        reportEntity.setReportUserId(0);
        reportEntity.setReportContent("这个小伙伴还没有人吐槽过他，你有什么要吐槽他的吗？点击下方按钮-吐槽TA一下-");
        reportEntity.setCreateTime(new Timestamp(System.currentTimeMillis()));
        reportEntity.setModifyTime(new Timestamp(System.currentTimeMillis()));
        reportEntity.setStatus(ConstantsValue.STATUS_NO_DEL);
        reportEntity.setIsReally(ConstantsValue.STATUS_TRUE);
        reportsMapper.insert(reportEntity);

        return ResponseWrapper.succeed(userVo);
    }


    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper getUserOpenId(String jscode,Long pid){
        return this.registerUser(jscode,pid);
    }



    /**
     * 绑定父级id
     * @param jscode
     * @param pid
     * @return
     */
    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper bindParent(String jscode,Long pid) {
        return this.registerUser(jscode,pid);
    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public UserVo checkName(Integer uid,String realName, String code) {

        UserEntity userEntity = new UserEntity();
        userEntity.setRealName(realName);
        userEntity.setCode(code);
        userEntity = userMapper.selectOne(userEntity);
        if (userEntity == null){
            throw new ApiException(ErrorCodeEnum.PARAM_200037);
        }
        if (userEntity.getCodeModify().getTime() < System.currentTimeMillis()){
            throw new ApiException(ErrorCodeEnum.PARAM_200031);
        }


        UserEntity userCheck = new UserEntity();
        userCheck.setUserId(uid);
        userCheck = userMapper.selectOne(userCheck);

        //无论用户是否支付过，都先绑定上下级关系，方便用户支付时给上级结算佣金
        if (uid != userEntity.getUserId() && userCheck.getParentId() == null){
            final UserEntity threadUserEntity = userEntity;//被核查者成为上级
            final UserEntity threadUserCheck = userCheck;//核查者成为下级
            Future<Boolean> future = ThreadPoolsConstants.parentThreadPool.submit(new Runnable() {
                @Override
                public void run() {
                    //被核查对象将成为自己的上级，上级不能是自己，上级如果有人，则跳过
                    threadUserCheck.setParentId(threadUserEntity.getUserId());
                    userMapper.updateByPrimaryKey(threadUserCheck);
                    log.info("线程执行结束,用户ID{}，姓名:{}已成为用户ID{}，姓名:{}的上级",threadUserEntity.getUserId(),threadUserEntity.getRealName(),threadUserCheck.getUserId(),threadUserCheck.getRealName());
                }
            },true);

            try {
                if (!future.get(3000,TimeUnit.SECONDS)){
                    throw new ApiException(ErrorCodeEnum.SC1.code(),ErrorCodeEnum.SC1.msg());
                }
            } catch (InterruptedException e) {
//                e.printStackTrace();
                throw new ApiException(ErrorCodeEnum.WX1.code(),ErrorCodeEnum.WX1.msg());
            } catch (ExecutionException e) {
//                e.printStackTrace();
                throw new ApiException(ErrorCodeEnum.WX1.code(),ErrorCodeEnum.WX1.msg());
            } catch (TimeoutException e) {
                throw new ApiException(ErrorCodeEnum.WX1.code(),ErrorCodeEnum.WX1.msg());
            }
        }


        SomeValEntity ccp = new SomeValEntity();
        ccp.setKey1("closeOrOpenPay");
        String closeCheckPay = someValMapper.selectOne(ccp).getValue1();
        if (ConstantsValue.OPEN_PAY.equals(closeCheckPay)){
            if (userCheck.getIsAgent() == ConstantsValue.STATUS_NO_AGENT || (userCheck.getAgentModify().getTime() < System.currentTimeMillis())) {
                if (userCheck.getPayStatus() == ConstantsValue.STATUS_NO_PAY){
                    SomeValEntity someValEntity = new SomeValEntity();
                    someValEntity.setKey1(ExamineStatusEnum.getEnum(ConstantsValue.FEE_TYPE_CHECK).msg());
                    String fee = someValMapper.selectOne(someValEntity).getValue1();
                    throw new ApiException(ErrorCodeEnum.PARAM_200038.code(),ErrorCodeEnum.PARAM_200038.msg().replace("FEE", fee));
                }
                if (userCheck.getPayExpire().getTime() < System.currentTimeMillis()){
                    SomeValEntity someValEntity = new SomeValEntity();
                    someValEntity.setKey1(ExamineStatusEnum.getEnum(ConstantsValue.FEE_TYPE_CON).msg());
                    String fee = someValMapper.selectOne(someValEntity).getValue1();
                    throw new ApiException(ErrorCodeEnum.PARAM_200039.code(),ErrorCodeEnum.PARAM_200039.msg().replace("FEE", fee));
                }
            }
        }




        CheckRecordEntity checkRecordEntity = new CheckRecordEntity();
        checkRecordEntity.setToUserId(uid);
        checkRecordEntity.setFromUserId(userEntity.getUserId());
        checkRecordEntity = checkRecordMapper.selectOne(checkRecordEntity);
        if (checkRecordEntity == null){
            checkRecordEntity = new CheckRecordEntity();
            checkRecordEntity.setToUserId(uid);
            checkRecordEntity.setFromUserId(userEntity.getUserId());
            checkRecordEntity.setMobile(userEntity.getMobile());
            checkRecordEntity.setRealHead(userEntity.getRealHead());
            checkRecordEntity.setRealName(userEntity.getRealName());
            checkRecordEntity.setAge(userEntity.getAge());
            checkRecordEntity.setSex(userEntity.getSex());
            checkRecordEntity.setStatus(ConstantsValue.STATUS_NO_DEL);
            checkRecordEntity.setAddr(userEntity.getAddr());
            checkRecordMapper.insert(checkRecordEntity);
        }else{
            checkRecordEntity.setMobile(userEntity.getMobile());
            checkRecordEntity.setRealHead(userEntity.getRealHead());
            checkRecordEntity.setAddr(userEntity.getAddr());
            checkRecordMapper.updateByPrimaryKey(checkRecordEntity);
        }

        UserVo userVo = new UserVo();
        userVo.setUserId(userEntity.getUserId());
        userVo.setMobile(userEntity.getMobile().substring(0,3)+"*****"+userEntity.getMobile().substring(8,11));
        userVo.setRealHead(userEntity.getRealHead());
        userVo.setRealName(userEntity.getRealName());
        userVo.setSex(userEntity.getSex());
        userVo.setAge(userEntity.getAge());
        userVo.setRecordId(checkRecordEntity.getRecordId());
        return userVo;

    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public String updateCode(Integer userId) {

        String code =MakeSixNums.random6();
        UserEntity userEntity = new UserEntity();
        userEntity.setUserId(userId);
        userEntity = userMapper.selectOne(userEntity);

        if (userEntity == null){
            throw new ApiException(ErrorCodeEnum.SW50.code(),ErrorCodeEnum.SW50.msg());
        }
        if (userEntity.getAuthStatus()!= ConstantsValue.AUTH_OK){
            throw new ApiException(ErrorCodeEnum.PARAM_200032.code(),ErrorCodeEnum.PARAM_200032.msg());
        }
        if (userEntity.getBlack()== ConstantsValue.STATUS_BLACK){
            throw new ApiException(ErrorCodeEnum.TK1012.code(),ErrorCodeEnum.TK1012.msg());
        }
        if (userEntity.getStatus()== ConstantsValue.STATUS_DEL){
            throw new ApiException(ErrorCodeEnum.SW50.code(),ErrorCodeEnum.SW50.msg());
        }

        userEntity.setCode(code);
        long ddd = System.currentTimeMillis()+ ConstantsValue.TIME_ONE_DAY;
//        log.info(ddd + "--");
        userEntity.setCodeModify(new Timestamp(ddd));
        userEntity.setModifyTime(new Timestamp(System.currentTimeMillis()));
        userMapper.updateByPrimaryKey(userEntity);
        return code;

    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public String getCode(Integer userId) {
        UserEntity userEntity = new UserEntity();
        userEntity.setUserId(userId);
        userEntity = userMapper.selectOne(userEntity);
        if (userEntity == null){
            throw new ApiException(ErrorCodeEnum.SW50.code(),ErrorCodeEnum.SW50.msg());
        }
        if (userEntity.getAuthStatus()!= ConstantsValue.AUTH_OK){
            throw new ApiException(ErrorCodeEnum.PARAM_200032.code(),ErrorCodeEnum.PARAM_200032.msg());
        }
        if (userEntity.getBlack()== ConstantsValue.STATUS_BLACK){
            throw new ApiException(ErrorCodeEnum.TK1012.code(),ErrorCodeEnum.TK1012.msg());
        }
        if (userEntity.getStatus()== ConstantsValue.STATUS_DEL){
            throw new ApiException(ErrorCodeEnum.SW50.code(),ErrorCodeEnum.SW50.msg());
        }
        if (userEntity.getCodeModify().getTime() < System.currentTimeMillis()){
            String code =MakeSixNums.random6();
            userEntity.setCode(code);
            userEntity.setCodeModify(new Timestamp(System.currentTimeMillis() + ConstantsValue.TIME_ONE_DAY));
            userEntity.setModifyTime(new Timestamp(System.currentTimeMillis()));
            userMapper.updateByPrimaryKey(userEntity);
            return userEntity.getRealName() + "  " + code;
        }
        return userEntity.getRealName() + "  " + userEntity.getCode();
    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public List<CheckRecordVo> getRecords(Integer userId,Integer pageSize,Integer rows) {

        Example example=new Example(CheckRecordEntity.class);
        example.setOrderByClause("record_id desc");

        Example.Criteria criteria = example.createCriteria();
        if(userId!=null)
            criteria.andEqualTo("toUserId", userId);
//        if(StringUtils.isNotBlank(realName))
//            criteria.andLike("realName","%"+realName+"%");

        RowBounds rowBounds = RowBoundUtil.getRowBounds(rows, pageSize);
        List<CheckRecordEntity> checkRecordEntities = checkRecordMapper.selectByExampleAndRowBounds(example, rowBounds);

        List<CheckRecordVo> checkRecordVos = new ArrayList<>();
        for (CheckRecordEntity entity : checkRecordEntities){
            CheckRecordVo checkRecordVo = new CheckRecordVo();
            BeanUtils.copyProperties(entity,checkRecordVo);
            checkRecordVos.add(checkRecordVo);
        }
//        Collections.reverse(checkRecordVos); // 倒序排列
        return checkRecordVos;
    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public CheckRecordVo getRecordInfo(Integer id) {
        CheckRecordEntity checkRecordEntity = new CheckRecordEntity();
        checkRecordEntity.setRecordId(id);
        checkRecordEntity = checkRecordMapper.selectOne(checkRecordEntity);
        checkRecordEntity.setMobile(checkRecordEntity.getMobile().substring(0,3)+"*****"+checkRecordEntity.getMobile().substring(8,11));
        checkRecordEntity.setAddr(checkRecordEntity.getAddr().substring(0,6));
        CheckRecordVo checkRecordVo = new CheckRecordVo();
        BeanUtils.copyProperties(checkRecordEntity,checkRecordVo);
        return checkRecordVo;
    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public List<ReportVo> getReports(Integer userId, Integer pageSize, Integer rows) {
        Example example=new Example(ReportEntity.class);
        example.setOrderByClause("report_id desc");

        Example.Criteria criteria = example.createCriteria();
        if(userId!=null)
            criteria.andEqualTo("beReportUserId", userId);

        criteria.andEqualTo("isReally", ConstantsValue.STATUS_TRUE);

        RowBounds rowBounds = RowBoundUtil.getRowBounds(rows, pageSize);
        List<ReportEntity> reportEntities = reportsMapper.selectByExampleAndRowBounds(example, rowBounds);
//        Collections.reverse(reportEntities);

        List<ReportVo> reportVos = new ArrayList<>();
        for (ReportEntity entity : reportEntities){
            ReportVo reportVo = new ReportVo();
            BeanUtils.copyProperties(entity, reportVo);
            reportVos.add(reportVo);
        }
        return reportVos;
    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public void reportUser(Integer reportUserId, Integer beReportUserId, String reportContent) {

        if (reportUserId == beReportUserId){
            throw new ApiException(ErrorCodeEnum.PARAM_200040);
        }

        UserEntity userEntity = new UserEntity();
        userEntity.setUserId(reportUserId);
        userEntity = userMapper.selectOne(userEntity);

        ReportEntity reportEntity = new ReportEntity();
        reportEntity.setBeReportUserId(beReportUserId);
        reportEntity.setReportUserId(reportUserId);
        reportEntity.setIsReally(ConstantsValue.STATUS_TRUE);
        int count = reportsMapper.selectCount(reportEntity);
        if (count >= 1){//已经吐槽过一次，一个用户只能吐槽另一个用户一次。
            throw new ApiException(ErrorCodeEnum.PARAM_200050);
        }
        reportEntity.setReportUserName(userEntity.getRealName().replace(userEntity.getRealName().substring(1,2), "*"));
        reportEntity.setReportContent(reportContent);
        reportEntity.setCreateTime(new Timestamp(System.currentTimeMillis()));
        reportEntity.setModifyTime(new Timestamp(System.currentTimeMillis()));
        reportEntity.setStatus(ConstantsValue.STATUS_NO_DEL);
        reportEntity.setIsReally(ConstantsValue.STATUS_TRUE);//审核中：STATUS_EXAMINE
        reportsMapper.insert(reportEntity);

        //用户吐槽后，删除"系统吐槽"的记录
        Example example=new Example(ReportEntity.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("beReportUserId",beReportUserId);
        criteria.andEqualTo("reportUserId",0);
        reportsMapper.deleteByExample(example);

    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper visitCode(Integer userId) {
        UserEntity userEntity = new UserEntity();
        userEntity.setUserId(userId);
        userEntity = userMapper.selectOne(userEntity);

        if (userEntity == null){
            throw new ApiException(ErrorCodeEnum.SW50);
        }
//        if (userEntity.getAuthStatus() != ConstantsValue.AUTH_OK){
//            throw new ApiException(ErrorCodeEnum.PARAM_200032);
//        }
        if (userEntity.getBlack() == ConstantsValue.STATUS_BLACK){
            throw new ApiException(ErrorCodeEnum.TK1012);
        }
        if (userEntity.getStatus() == ConstantsValue.STATUS_DEL){
            throw new ApiException(ErrorCodeEnum.SW50);
        }
        if (userEntity.getIsAgent() == ConstantsValue.STATUS_AGENT && (userEntity.getAgentModify().getTime() > System.currentTimeMillis())) {
            throw new ApiException(ErrorCodeEnum.PARAM_200041);
        }

        return ResponseWrapper.succeed();
    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public List<RevenuesEntity> myRevenues(Integer userId, Integer pageSize, Integer rows) {
        Example example=new Example(RevenuesEntity.class);
        example.setOrderByClause("id desc");

        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId",userId);

        RowBounds rowBounds = RowBoundUtil.getRowBounds(rows, pageSize);

        List<RevenuesEntity> revenuesEntities = revenuesMapper.selectByExampleAndRowBounds(example, rowBounds);
        return revenuesEntities;

    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public UserVo userRevenue(Integer userId) {
        UserEntity userEntity = new UserEntity();
        userEntity.setUserId(userId);
        userEntity = userMapper.selectOne(userEntity);

        UserVo userVo = new UserVo();
        userVo.setTotalRevenue(userEntity.getTotalRevenue());
        userVo.setUndrawn(userEntity.getUndrawn());
        userVo.setDrawn(userEntity.getDrawn());
        userVo.setIsAgent(userEntity.getIsAgent());

        return userVo;
    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public void applyAuth(Integer userId, String head, String cardA, String cardB, String mobile, String code) {
        String vcode = redisService.getString(ConstantsValue.VERIFICATION_CODE + mobile);
        if (!code.equals(vcode)){
            throw new ApiException(ErrorCodeEnum.TK1015);
        }

        ApplyAuthEntity applyAuthEntity = new ApplyAuthEntity();
        applyAuthEntity.setUserId(userId);
        applyAuthEntity = applyAuthMapper.selectOne(applyAuthEntity);
        applyAuthEntity.setIsExamina(ConstantsValue.NO_EXAMINE);
        applyAuthEntity.setHead(head);
        applyAuthEntity.setCardA(cardA);
        applyAuthEntity.setCardB(cardB);
        applyAuthEntity.setStatus(ConstantsValue.STATUS_NO_DEL);
        applyAuthMapper.updateByPrimaryKey(applyAuthEntity);

        // 手机三要素认证： 手机号，姓名，身份证一致
        if(!DescribeZones.PhoneVerification(applyAuthEntity.getRealName(),applyAuthEntity.getIdCard(),mobile,redisService.getString(ConstantsValue.WX_COFIG + "SECRET_ID"),redisService.getString(ConstantsValue.WX_COFIG + "SECRET_KEY"))){
            throw new ApiException(ErrorCodeEnum.PARAM_200045);
        }

        UserEntity userEntity = new UserEntity();
        userEntity.setUserId(userId);
        userEntity = userMapper.selectOne(userEntity);
        userEntity.setMobile(mobile);
        userEntity.setAuthStatus(ConstantsValue.AUTH_ING);
        userMapper.updateByPrimaryKey(userEntity);

        redisService.deleteString(ConstantsValue.VERIFICATION_CODE + mobile);

    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public String authStatus(Integer userId) {
        UserEntity userEntity = new UserEntity();
        userEntity.setUserId(userId);

        userEntity = userMapper.selectOne(userEntity);

        return String.valueOf(userEntity.getAuthStatus());
    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public void updateAuth(Integer id, String status, String rname, String year, String mouth, String day, String idc, String nation, String sex, String addr) {
        ApplyAuthEntity applyAuthEntity = new ApplyAuthEntity();
        applyAuthEntity.setId(id);
        applyAuthEntity = applyAuthMapper.selectOne(applyAuthEntity);
        applyAuthEntity.setRealName(rname);
        applyAuthEntity.setYear(year);
        applyAuthEntity.setMouth(mouth);
        applyAuthEntity.setDay(day);
        applyAuthEntity.setIdCard(idc);
        applyAuthEntity.setNation(nation);
        applyAuthEntity.setSex(sex);
        applyAuthEntity.setAddr(addr);
        applyAuthMapper.updateByPrimaryKey(applyAuthEntity);

        UserEntity userEntity = new UserEntity();
        userEntity.setUserId(applyAuthEntity.getUserId());
        userEntity = userMapper.selectOne(userEntity);
        userEntity.setAuthStatus(Integer.parseInt(status) == ConstantsValue.AUTH_OK ? ConstantsValue.AUTH_OK : ConstantsValue.AUTH_NO_OK);
        userEntity.setModifyTime(new Timestamp(new Date().getTime()));
        if (Integer.parseInt(status) == ConstantsValue.AUTH_OK){
            userEntity.setRealName(applyAuthEntity.getRealName());
            userEntity.setHead(applyAuthEntity.getHead());
            userEntity.setAddr(applyAuthEntity.getAddr());
            userEntity.setSex(applyAuthEntity.getSex());
            userEntity.setAge(applyAuthEntity.getYear());
            userEntity.setIdCard(applyAuthEntity.getIdCard());
            userEntity.setRealHead(applyAuthEntity.getHead());

            String code =MakeSixNums.random6();
            userEntity.setCode(code);
            userEntity.setCodeModify(new Timestamp(System.currentTimeMillis() + ConstantsValue.TIME_ONE_DAY));
        }
        userMapper.updateByPrimaryKey(userEntity);

        applyAuthEntity.setIsExamina(Integer.parseInt(status) == ConstantsValue.AUTH_OK ? ConstantsValue.EXAMINE_OK : ConstantsValue.EXAMINE_NO_OK);
        applyAuthEntity.setModifyTime(new Timestamp(new Date().getTime()));
        applyAuthMapper.updateByPrimaryKey(applyAuthEntity);

    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper authList(Integer page, Integer limit, Integer status) {
        Example example=new Example(ApplyAuthEntity.class);
        example.setOrderByClause("id desc");

        Example.Criteria criteria = example.createCriteria();
        if (status != null)
            criteria.andEqualTo("isExamina", status);
        RowBounds rowBounds = RowBoundUtil.getRowBounds(limit, page);
        List<ApplyAuthEntity> applyAuthEntities = applyAuthMapper.selectByExampleAndRowBounds(example, rowBounds);

        int count = applyAuthMapper.selectCountByExample(example);
        return ResponseWrapper.succeed(count, applyAuthEntities);
    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public void sendVerificationCode(String mobile) {

        String vcode = String.valueOf((int)(Math.random()*(999999-100000+1)+100000));

        redisService.setString(ConstantsValue.VERIFICATION_CODE + mobile, vcode);

        SendSms.send(vcode,mobile,redisService.getString(ConstantsValue.WX_COFIG + "SECRET_ID"),redisService.getString(ConstantsValue.WX_COFIG + "SECRET_KEY"));

    }
    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper userList(Integer page, Integer limit) {
        UserEntity userEntity = new UserEntity();
        int count = userMapper.selectCount(userEntity);

        Example example=new Example(UserEntity.class);
        example.setOrderByClause("user_id desc");

        Example.Criteria criteria = example.createCriteria();
        criteria.andGreaterThan("userId",0);

        RowBounds rowBounds = RowBoundUtil.getRowBounds(limit, page);
        List<UserEntity> userEntities = userMapper.selectByExampleAndRowBounds(example, rowBounds);

        return ResponseWrapper.succeed(count, userEntities);
    }
    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper userRevenueList(Integer page, Integer limit, Integer userId) {
        RevenuesEntity revenuesEntity = new RevenuesEntity();
        revenuesEntity.setUserId(userId);
        int count = revenuesMapper.selectCount(revenuesEntity);
        RowBounds rowBounds = new RowBounds(limit,page);
        List<RevenuesEntity> revenuesEntities = revenuesMapper.selectByRowBounds(revenuesEntity, rowBounds);

        return ResponseWrapper.succeed(count, revenuesEntities);
    }
    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper userWithDrawnList(Integer page, Integer limit, Integer userId) {
        UserWithDrawnEntity userWithDrawnEntity = new UserWithDrawnEntity();
        userWithDrawnEntity.setUserId(userId);
        int count = userWithDrawnMapper.selectCount(userWithDrawnEntity);
        RowBounds rowBounds = new RowBounds(limit,page);
        List<UserWithDrawnEntity> userWithDrawnEntities = userWithDrawnMapper.selectByRowBounds(userWithDrawnEntity, rowBounds);

        return ResponseWrapper.succeed(count, userWithDrawnEntities);
    }


    /**
     * 获取用户推广二维码
     *
     * @param userId
     * @return
     */
    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper getQrCode(Long userId) {

        UserQrCode userQrCode = new UserQrCode();
        userQrCode.setUserId(userId);
        String qrCode = userQrCodeMapper.selectOne(userQrCode).getQrCode();

        return ResponseWrapper.succeed(qrCode);
    }

    /**
     * 获取 总收益 总支出 已支出 未支出 平台用户数 平台代理商数 平台普通用户数
     *
     * @return
     */
    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper getDatas() {

        JSONObject jsonObject = new JSONObject();

        CapitalEntity capitalEntity = new CapitalEntity();
        capitalEntity.setId(1);
        capitalEntity = capitalMapper.selectOne(capitalEntity);

        jsonObject.put("totalRevenue",capitalEntity.getTotalRevenue());//平台总收益
        jsonObject.put("totalExpend",capitalEntity.getTotalExpend());//平台总支出
        jsonObject.put("alreadyExpend",capitalEntity.getAlreadyExpend());//平台已支出

        BigDecimal waitExpend = new BigDecimal(capitalEntity.getTotalExpend()).subtract(new BigDecimal(capitalEntity.getAlreadyExpend())).setScale(ConstantsValue.SCALE_2,BigDecimal.ROUND_HALF_UP);
        jsonObject.put("waitExpend",waitExpend.toString());//平台未支出

        UserEntity dispUser = new UserEntity();
        dispUser.setIsAgent(ConstantsValue.STATUS_AGENT);
        int dispUserCount = userMapper.selectCount(dispUser);
        jsonObject.put("dispUserCount",dispUserCount);//平台代理商总数

        UserEntity commonUser = new UserEntity();
        commonUser.setIsAgent(ConstantsValue.STATUS_NO_AGENT);
        int commonUserCount = userMapper.selectCount(commonUser);
        jsonObject.put("commonUserCount",commonUserCount);//平台普通用户总数

        int userCount = dispUserCount + commonUserCount;
        jsonObject.put("userCount",userCount);//平台用户总数

        return ResponseWrapper.succeed(jsonObject);
    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper userWithDrawn(Integer userId) {

        SomeValEntity someValEntity = new SomeValEntity();
        someValEntity.setKey1("drawnStatus");
        someValEntity = someValMapper.selectOne(someValEntity);
        if (ConstantsValue.STATUS_NO_DRAWN == Integer.parseInt(someValEntity.getValue1())){
            throw new ApiException(ErrorCodeEnum.PARAM_200047);
        }

        SomeValEntity autoTransfer = new SomeValEntity();
        autoTransfer.setKey1("autoTransfer");
        autoTransfer = someValMapper.selectOne(autoTransfer);

        UserEntity txUser = new UserEntity();
        txUser.setUserId(userId);
        txUser = userMapper.selectOne(txUser);

        if (txUser.getAuthStatus() != ConstantsValue.AUTH_OK){
            throw new ApiException(ErrorCodeEnum.PARAM_200049);
        }

        if (txUser.getNoDrawn()== ConstantsValue.STATUS_NO_DRAWN){
            throw new ApiException(ErrorCodeEnum.PARAM_200048);
        }

        BigDecimal undrawn = new BigDecimal(txUser.getUndrawn());
        if (undrawn.doubleValue() < ConstantsValue.RMB100){
            throw new ApiException(ErrorCodeEnum.PARAM_200044);
        }
        if (undrawn.doubleValue() > ConstantsValue.RMB10000){
            throw new ApiException(ErrorCodeEnum.PARAM_200051);
        }
        //更新用户的 待提现，已提现 数据
        BigDecimal drawn = new BigDecimal(txUser.getDrawn());
        txUser.setUndrawn("0");
        txUser.setDrawn(undrawn.add(drawn).setScale(ConstantsValue.SCALE_2,BigDecimal.ROUND_HALF_UP).toString());
        txUser.setModifyTime(new Timestamp(System.currentTimeMillis()));
        userMapper.updateByPrimaryKey(txUser);

        //累计平台已提现（已支出）的情况
        CapitalEntity capitalEntity = capitalMapper.selectAll().get(0);
        String ae = new BigDecimal(capitalEntity.getAlreadyExpend()).add(undrawn).setScale(ConstantsValue.SCALE_2, BigDecimal.ROUND_HALF_UP).toString();
        capitalEntity.setAlreadyExpend(ae);
        capitalMapper.updateByPrimaryKey(capitalEntity);

        if (ConstantsValue.AUTO_TRANSFER == Integer.parseInt(autoTransfer.getValue1())){
            return this.autoTransfer(txUser,undrawn);//自动提现
        }else{
            //记录申请，手动给用户提现，因为企业支付要90天后才能使用
            return this.manualTransfer(txUser,undrawn);
        }

    }

    private ResponseWrapper autoTransfer(UserEntity txUser,BigDecimal undrawn){

        String nonceStr = WXPayUtil.generateUUID();
        String partnerTradeNo = OrderUUID.getOrderIdByUUId();
        String amount = String.valueOf(undrawn.multiply(ConstantsValue.ONEHUNRAY).intValue());
        String desc = "用户 " + txUser.getRealName() + " 收益提现";
        Map<String, String> res = new HashMap<>();
        res.put("mch_appid", redisService.getString(ConstantsValue.WX_COFIG + "WX_APPID"));//商户账号appid
        res.put("mchid", redisService.getString(ConstantsValue.WX_COFIG + "MCH_ID"));//商户号
        res.put("nonce_str",nonceStr);//随机字符串
        res.put("partner_trade_no", partnerTradeNo);//商户订单号
        res.put("openid", txUser.getOpenId());//用户openid
        res.put("check_name", ConstantsValue.FORCE_CHECK);//校验用户姓名选项
        res.put("re_user_name", txUser.getRealName());//收款用户姓名
        res.put("amount", amount);//金额
        res.put("desc", desc);//企业付款备注
        String paySign = null;
        try {
            paySign = WXPayUtil.generateSignature(res, redisService.getString(ConstantsValue.WX_COFIG + "MCH_KEY"));

            log.info("序号：{},数据：{}",1,paySign);
            res.put("sign",paySign);
            WXPay wxpay = new WXPay(new MyConfig(redisService.getString(ConstantsValue.WX_COFIG + "WX_APPID"),redisService.getString(ConstantsValue.WX_COFIG + "MCH_ID"),redisService.getString(ConstantsValue.WX_COFIG + "MCH_KEY")));
            Map<String, String> resp = wxpay.transfers(res);//企业付款接口
            WxTransferPayEntity wxTransferPayEntity = new WxTransferPayEntity();
            wxTransferPayEntity.setMchAppid(redisService.getString(ConstantsValue.WX_COFIG + "WX_APPID"));
            wxTransferPayEntity.setMchid(redisService.getString(ConstantsValue.WX_COFIG + "MCH_ID"));
            wxTransferPayEntity.setNonceStr(nonceStr);
            wxTransferPayEntity.setPartnerTradeNo(partnerTradeNo);
            wxTransferPayEntity.setOpenid(txUser.getOpenId());
            wxTransferPayEntity.setCheckName(ConstantsValue.NO_CHECK);
            wxTransferPayEntity.setReUserName(txUser.getRealName());
            wxTransferPayEntity.setAmount(undrawn.toString());
            wxTransferPayEntity.setRemarkDesc(desc);
            wxTransferPayEntity.setCreateTime(new Timestamp(System.currentTimeMillis()));
            wxTransferPayEntity.setStatus(ConstantsValue.STATUS_NO_DEL);
            wxTransferPayEntity.setTransferType(ConstantsValue.AUTO_TRANSFER);
            wxTransferPayEntity.setReturnCode(resp.get("return_code"));
            wxTransferPayEntity.setReturnMsg(resp.get("return_msg"));


            log.info("序号：{},数据：{}",2,resp);
            if (ConstantsValue.FAIL.equals(resp.get("return_code"))){//通信失败
                throw new ApiException(ErrorCodeEnum.WX1);
            }else{

                log.info("序号：{},数据：{}",3,resp);
                //return_code 为success 时有返回下列字段
                wxTransferPayEntity.setResultCode(resp.get("result_code"));
                wxTransferPayEntity.setErrCode(resp.get("err_code"));
                wxTransferPayEntity.setErrCodeDes(resp.get("err_code_des"));
                if (ConstantsValue.FAIL.equals(resp.get("result_code"))){//通信成功，业务失败
                    //以下errcode ，系统务必使用原来的商户订单号重试提现操作
                    if ("NOTENOUGH".equals(wxTransferPayEntity.getErrCode())
                            || "SYSTEMERROR".equals(wxTransferPayEntity.getErrCode())
                            || "NAME_MISMATCH".equals(wxTransferPayEntity.getErrCode())
                            || "SIGN_ERROR".equals(wxTransferPayEntity.getErrCode())
                            || "FREQ_LIMIT".equals(wxTransferPayEntity.getErrCode())
                            || "MONEY_LIMIT".equals(wxTransferPayEntity.getErrCode())
                            || "CA_ERROR".equals(wxTransferPayEntity.getErrCode())
                            || "V2_ACCOUNT_SIMPLE_BAN".equals(wxTransferPayEntity.getErrCode())
                            || "PARAM_IS_NOT_UTF8".equals(wxTransferPayEntity.getErrCode())
                            || "SENDNUM_LIMIT".equals(wxTransferPayEntity.getErrCode())){
                        return ResponseWrapper.failed(ErrorCodeEnum.WP8015);

                    }else if ("SEND_FAILED".equals(wxTransferPayEntity.getErrCode())){//付款错误，请查单确认付款结果
                        return ResponseWrapper.failed(ErrorCodeEnum.WP8022);
                    }else{//其他原因直接回退
                        throw new ApiException(ErrorCodeEnum.WP8021);
                    }
                }else{
                    //result_code 为success 时有返回下列字段
                    wxTransferPayEntity.setPaymentNo(resp.get("payment_no"));
                    wxTransferPayEntity.setPaymentTime(resp.get("payment_time"));
                }
                wxTransferPayMapper.insert(wxTransferPayEntity);
                return ResponseWrapper.succeed();//提现成功
            }
        } catch (Exception e) {
            log.info("序号：{}",4);
            throw new ApiException(ErrorCodeEnum.WP8016);
        }
    }

    private ResponseWrapper manualTransfer(UserEntity txUser,BigDecimal undrawn){

        String nonceStr = WXPayUtil.generateUUID();
        String partnerTradeNo = OrderUUID.getOrderIdByUUId();
        String amount = String.valueOf(undrawn.multiply(ConstantsValue.ONEHUNRAY).intValue());
        String desc = "用户 " + txUser.getRealName() + " 收益提现";

        WxTransferPayEntity wxTransferPayEntity = new WxTransferPayEntity();
        wxTransferPayEntity.setMchAppid(redisService.getString(ConstantsValue.WX_COFIG + "WX_APPID"));
        wxTransferPayEntity.setMchid(redisService.getString(ConstantsValue.WX_COFIG + "MCH_ID"));
        wxTransferPayEntity.setNonceStr(nonceStr);
        wxTransferPayEntity.setPartnerTradeNo(partnerTradeNo);
        wxTransferPayEntity.setOpenid(txUser.getOpenId());
        wxTransferPayEntity.setCheckName(ConstantsValue.NO_CHECK);
        wxTransferPayEntity.setReUserName(txUser.getRealName());
        wxTransferPayEntity.setAmount(undrawn.toString());
        wxTransferPayEntity.setRemarkDesc(desc);
        wxTransferPayEntity.setCreateTime(new Timestamp(System.currentTimeMillis()));
        wxTransferPayEntity.setStatus(ConstantsValue.STATUS_NO_DEL);
        wxTransferPayEntity.setTransferType(ConstantsValue.MANUAL_TRANSFER);

        wxTransferPayMapper.insert(wxTransferPayEntity);
        return ResponseWrapper.succeed();//提现成功

    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper getChildRecords(Integer userId, Integer pageSize, Integer rows) {

        UserEntity userEntity = new UserEntity();
        userEntity.setParentId(userId);
        int count = userMapper.selectCount(userEntity);

        RowBounds rowBounds = RowBoundUtil.getRowBounds(rows, pageSize);
        List<UserEntity> userEntities = userMapper.selectByRowBounds(userEntity,rowBounds);

        List<UserVo> userVos = new ArrayList<>();
        for (UserEntity entity : userEntities){
            UserVo userVo = new UserVo();
            BeanUtils.copyProperties(entity, userVo);
            userVos.add(userVo);
        }

        return ResponseWrapper.succeed(count, userVos);
    }
    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper noDrawn(Integer userId) {
        UserEntity userEntity = new UserEntity();
        userEntity.setUserId(userId);
        userEntity = userMapper.selectOne(userEntity);
        if (userEntity.getNoDrawn() == ConstantsValue.STATUS_DRAWN){
            userEntity.setNoDrawn(ConstantsValue.STATUS_NO_DRAWN);
            userEntity.setModifyTime(new Timestamp(System.currentTimeMillis()));
            userMapper.updateByPrimaryKey(userEntity);
        }
        return ResponseWrapper.succeed();
    }
    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper closeOrOpenDrawnStatus() {
        SomeValEntity someValEntity = new SomeValEntity();
        someValEntity.setKey1("drawnStatus");
        someValEntity = someValMapper.selectOne(someValEntity);
        Integer drawnStatus = Integer.valueOf(someValEntity.getValue1());
        someValEntity.setValue1(String.valueOf(drawnStatus == ConstantsValue.STATUS_NO_DRAWN ? ConstantsValue.STATUS_DRAWN : ConstantsValue.STATUS_NO_DRAWN));
        someValMapper.updateByPrimaryKey(someValEntity);
        return ResponseWrapper.succeed(someValEntity.getValue1());
    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper getDrawnStatus() {
        SomeValEntity someValEntity = new SomeValEntity();
        someValEntity.setKey1("drawnStatus");
        String drawnStatus = someValMapper.selectOne(someValEntity).getValue1();

        return ResponseWrapper.succeed(drawnStatus);
    }


    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper closeOrOpenPay() {

        SomeValEntity someValEntity = new SomeValEntity();
        someValEntity.setKey1("closeOrOpenPay");
        someValEntity = someValMapper.selectOne(someValEntity);
        String closeCheckPay = someValEntity.getValue1();

        if (ConstantsValue.CLOSE_PAY.equals(closeCheckPay)){
            someValEntity.setValue1(ConstantsValue.OPEN_PAY);
        }else{
            someValEntity.setValue1(ConstantsValue.CLOSE_PAY);
        }
        someValMapper.updateByPrimaryKey(someValEntity);

        return ResponseWrapper.succeed();
    }
    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper getPayStatus() {
        SomeValEntity someValEntity = new SomeValEntity();
        someValEntity.setKey1("closeOrOpenPay");
        String payStatus = someValMapper.selectOne(someValEntity).getValue1();

        return ResponseWrapper.succeed(payStatus);
    }


    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public String wxpayCallback(Map<String,String > m) {

        //更新订单信息
        WxPayOrderlEntity wxPayOrderlEntity = new WxPayOrderlEntity();
        wxPayOrderlEntity.setOutTradeNo(m.get("out_trade_no"));
        wxPayOrderlEntity = wxPayOrderMapper.selectOne(wxPayOrderlEntity);

        //当收到通知进行处理时，首先检查对应业务数据的状态，判断该通知是否已经处理过，如果没有处理过再进行处理，如果处理过直接返回结果成功。
        if (ConstantsValue.SUCCESS.equals(wxPayOrderlEntity.getResultCode())){//如果等于SUCCESS，无需继续处理。
            return XmlConvertMapUtil.returnSuccess();
        }

        try {
            Map<String, String> parameters = new HashMap<>();
            parameters.put("appid", m.get("appid"));//小程序ID
            parameters.put("mch_id", m.get("mch_id"));//商户号
            parameters.put("nonce_str", m.get("nonce_str"));//随机字符串
            parameters.put("openid", m.get("openid"));//用户标识
            parameters.put("is_subscribe", m.get("is_subscribe"));//用户是否关注公众账号，Y-关注，N-未关注
            parameters.put("trade_type", m.get("trade_type"));//交易类型
            parameters.put("bank_type", m.get("bank_type"));//付款银行
            parameters.put("total_fee", m.get("total_fee"));//订单总金额，单位为分
            parameters.put("cash_fee", m.get("cash_fee"));//现金支付金额
            parameters.put("transaction_id", m.get("transaction_id"));//微信支付订单号
            parameters.put("out_trade_no", m.get("out_trade_no"));//商户订单号
            parameters.put("time_end", m.get("time_end"));//支付完成时间
            parameters.put("fee_type", m.get("fee_type"));//货币种类
            parameters.put("attach", m.get("attach"));//商家数据包，自定义，原样返回
            parameters.put("result_code", m.get("result_code"));//
            parameters.put("return_code", m.get("return_code"));//
            String mySign = WXPayUtil.generateSignature(parameters, redisService.getString(ConstantsValue.WX_COFIG + "MCH_KEY"));

            //商户系统对于支付结果通知的内容一定要做签名验证
            if (!m.get("sign").equals(mySign)) {
                throw new ApiException(ErrorCodeEnum.WX_SIGN_DIFF);
            }
            //此次请求微信查询api，确保微信系统有这笔订单，防止接口被恶意请求，造成资金损失
            Map<String, String> res = new HashMap<>();
            res.put("appid", redisService.getString(ConstantsValue.WX_COFIG + "WX_APPID"));
            res.put("mch_id", redisService.getString(ConstantsValue.WX_COFIG + "MCH_ID"));
            res.put("transaction_id",m.get("transaction_id"));
            res.put("nonce_str", WXPayUtil.generateUUID());
            res.put("sign_type", ConstantsValue.SIGN_TYPE);
            String paySign = WXPayUtil.generateSignature(res,redisService.getString(ConstantsValue.WX_COFIG + "MCH_KEY"));
            res.put("sign",paySign);
            WXPay wxpay = new WXPay(new MyConfig(redisService.getString(ConstantsValue.WX_COFIG + "WX_APPID"),redisService.getString(ConstantsValue.WX_COFIG + "MCH_ID"),redisService.getString(ConstantsValue.WX_COFIG + "MCH_KEY")));
            Map<String, String> resp = wxpay.orderQuery(res);
            if(ConstantsValue.FAIL.equals(resp.get("return_code"))) {//查询失败，通信原因
                throw new ApiException(ErrorCodeEnum.WP8013);
            }else{
                if (ConstantsValue.FAIL.equals(resp.get("result_code"))){//业务失败
                    throw new ApiException(ErrorCodeEnum.WP8013);
                }else{
                    if(!ConstantsValue.SUCCESS.equals(resp.get("trade_state"))){//业务失败具体原因
                        throw new ApiException(ErrorCodeEnum.WP8012.code(),String.format(ErrorCodeEnum.WP8012.msg(),resp.get("trade_state")));
                    }
                }
            }


            //校验返回的订单金额是否与商户侧的订单金额一致
            String ttff = String.valueOf(new BigDecimal(wxPayOrderlEntity.getTotalFee()).multiply(ConstantsValue.ONEHUNRAY).intValue());
            if (!m.get("total_fee").equals(ttff)){
                throw new ApiException(ErrorCodeEnum.WP8011);
            }

            wxPayOrderlEntity.setReturnCode(m.get("return_code"));
            wxPayOrderlEntity.setReturnMsg(m.get("return_msg"));
            if (ConstantsValue.FAIL.equals(m.get("return_code"))) {//通信异常处理
                wxPayOrderMapper.updateByPrimaryKey(wxPayOrderlEntity);
                return XmlConvertMapUtil.returnFail();//throw new ApiException(ErrorCodeEnum.WP8017);
            }
            wxPayOrderlEntity.setResultCode(m.get("result_code"));
            wxPayOrderlEntity.setErrCode(m.get("err_code"));
            wxPayOrderlEntity.setErrCodeDesc(m.get("err_code_desc"));
            wxPayOrderlEntity.setBankType(m.get("bank_type"));
            wxPayOrderlEntity.setFeeType(m.get("fee_type"));
            wxPayOrderlEntity.setIsSubscribe(m.get("is_subscribe"));
            wxPayOrderlEntity.setTimeEnd(m.get("time_end"));
            wxPayOrderlEntity.setTransactionId(m.get("transaction_id"));
            wxPayOrderMapper.updateByPrimaryKey(wxPayOrderlEntity);

            if (ConstantsValue.FAIL.equals(m.get("result_code"))) {//业务失败处理
                return XmlConvertMapUtil.returnFail();//throw new ApiException(ErrorCodeEnum.WX_RESULT_CODE_FAILD);
            }

            //此次回调的金额
            String totalFee = m.get("total_fee");
            BigDecimal totalFee1 = new BigDecimal(totalFee).divide(ConstantsValue.ONEHUNRAY,ConstantsValue.SCALE_2,BigDecimal.ROUND_HALF_UP);

            //累计平台总的收益情况
            CapitalEntity capitalEntity = new CapitalEntity();
            capitalEntity.setId(1);
            capitalEntity = capitalMapper.selectOne(capitalEntity);
            String tr = new BigDecimal(capitalEntity.getTotalRevenue()).add(totalFee1).setScale(ConstantsValue.SCALE_2, BigDecimal.ROUND_HALF_UP).toString();
            capitalEntity.setTotalRevenue(tr);


            //处理费用业务
            UserEntity userEntity = new UserEntity();
            userEntity.setOpenId(m.get("openid"));
            userEntity = userMapper.selectOne(userEntity);

            Integer parentId = userEntity.getParentId();
            String childName = userEntity.getRealName();

            UserEntity parentUser = new UserEntity();//上级
            if (ConstantsValue.FEE_TYPE_CHECK == Integer.parseInt(m.get("attach")) //核查月费
                    || ConstantsValue.FEE_TYPE_CON == Integer.parseInt(m.get("attach"))){//核查续费

                log.info("序号：{},描述：{},数据：{}",4,"核查月费,核查续费","");
                userEntity.setPayStatus(ConstantsValue.STATUS_PAY);
                userEntity.setPayExpire(new Timestamp(System.currentTimeMillis() + ConstantsValue.TIME_ONE_MOUTH));
                userEntity.setModifyTime(new Timestamp(System.currentTimeMillis()));

                //给上级分配佣金
                if (userEntity.getParentId() != null){
                    parentUser.setUserId(parentId);
                    parentUser = userMapper.selectOne(parentUser);
                    if (parentUser.getIsAgent()== ConstantsValue.STATUS_AGENT){//代理商佣金：90%
                        totalFee1 = totalFee1.multiply(ConstantsValue.PRESENT_90).setScale(ConstantsValue.SCALE_2,BigDecimal.ROUND_HALF_UP);
                    }else{//普通用户佣金：20%
                        totalFee1 = totalFee1.multiply(ConstantsValue.PRESENT_20).setScale(ConstantsValue.SCALE_2,BigDecimal.ROUND_HALF_UP);
                    }
                    String newTotalRevenue = new BigDecimal(parentUser.getTotalRevenue()).add(totalFee1)
                            .setScale(ConstantsValue.SCALE_2,BigDecimal.ROUND_HALF_UP).toString();
                    String newUndrawn = new BigDecimal(parentUser.getUndrawn()).add(totalFee1)
                            .setScale(ConstantsValue.SCALE_2,BigDecimal.ROUND_HALF_UP).toString();
                    parentUser.setUndrawn(newUndrawn);
                    parentUser.setTotalRevenue(newTotalRevenue);
                    userMapper.updateByPrimaryKey(parentUser);

                    //佣金收益记录
                    RevenuesEntity revenuesEntity = new RevenuesEntity();
                    revenuesEntity.setUserId(parentId);
                    revenuesEntity.setRFee(parentUser.getUndrawn());
                    revenuesEntity.setRName(childName);
                    revenuesEntity.setCreateTime(new Timestamp(System.currentTimeMillis()));
                    revenuesEntity.setStatus(ConstantsValue.STATUS_NO_DEL);
                    revenuesMapper.insert(revenuesEntity);
                }

            }else{//代理商加盟费

                log.info("序号：{},描述：{},数据：{}",5,"给上级分配佣金(代理商加盟费)","");
                userEntity.setPayStatus(ConstantsValue.STATUS_PAY);
                userEntity.setIsAgent(ConstantsValue.STATUS_AGENT);
                userEntity.setPayExpire(new Timestamp(System.currentTimeMillis() + ConstantsValue.TIME_FIVE_YEAR));//五年到期
                userEntity.setAgentModify(new Timestamp(System.currentTimeMillis() + ConstantsValue.TIME_FIVE_YEAR));//五年到期
                userEntity.setModifyTime(new Timestamp(System.currentTimeMillis()));

                //给上级分配佣金
                if (userEntity.getParentId() != null){
                    parentUser.setUserId(parentId);
                    parentUser = userMapper.selectOne(parentUser);

                    if (parentUser.getIsAgent() == ConstantsValue.STATUS_AGENT){//代理商佣金：加盟费用的20%
                        totalFee1 = totalFee1.multiply(ConstantsValue.PRESENT_20).setScale(ConstantsValue.SCALE_2,BigDecimal.ROUND_HALF_UP);
                        String newTotalRevenue = new BigDecimal(parentUser.getTotalRevenue()).add(totalFee1)
                                .setScale(ConstantsValue.SCALE_2,BigDecimal.ROUND_HALF_UP).toString();
                        String newUndrawn = new BigDecimal(parentUser.getUndrawn()).add(totalFee1)
                                .setScale(ConstantsValue.SCALE_2,BigDecimal.ROUND_HALF_UP).toString();
                        parentUser.setUndrawn(newUndrawn);
                        parentUser.setTotalRevenue(newTotalRevenue);
                        userMapper.updateByPrimaryKey(parentUser);
                    }

                    //佣金收益记录
                    RevenuesEntity revenuesEntity = new RevenuesEntity();
                    revenuesEntity.setUserId(parentId);
                    revenuesEntity.setRFee(parentUser.getUndrawn());
                    revenuesEntity.setRName(childName);
                    revenuesEntity.setCreateTime(new Timestamp(System.currentTimeMillis()));
                    revenuesEntity.setStatus(ConstantsValue.STATUS_NO_DEL);
                    revenuesMapper.insert(revenuesEntity);
                }
            }



            //累计平台总的支出
            capitalEntity.setTotalExpend(new BigDecimal(capitalEntity.getTotalExpend()).add(totalFee1).setScale(ConstantsValue.SCALE_2,BigDecimal.ROUND_HALF_UP).toString());
            capitalMapper.updateByPrimaryKey(capitalEntity);

            userMapper.updateByPrimaryKey(userEntity);

            return XmlConvertMapUtil.returnSuccess();
            //返回success，表示告诉微信我已经接收到了，不用再尝试通知我了。return "success";
        } catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper unifiedOrder(Integer userid, String type) {

        ExamineStatusEnum ee = ExamineStatusEnum.getEnum(Integer.parseInt(type));
        String body;
        if (ConstantsValue.FEE_TYPE_CHECK == ee.code()){
            body = ConstantsValue.CHECK_FEE;
        }else if(ConstantsValue.FEE_TYPE_CON == ee.code()){
            body = ConstantsValue.CHECK_FEE_2;
        }else{
            body = ConstantsValue.DIS_FEE;
        }

        UserEntity userEntity = new UserEntity();
        userEntity.setUserId(userid);
        userEntity = userMapper.selectOne(userEntity);

        SomeValEntity someValEntity = new SomeValEntity();
        someValEntity.setKey1(ee.msg());
        someValEntity = someValMapper.selectOne(someValEntity);

        BigDecimal fee = new BigDecimal(someValEntity.getValue1());
        BigDecimal totalFee = fee.multiply(ConstantsValue.ONEHUNRAY);

        Map<String, String> data = new HashMap<>();
        String orderNum = OrderUUID.getOrderIdByUUId();
        data.put("appid", redisService.getString(ConstantsValue.WX_COFIG + "WX_APPID"));//小程序appid
        data.put("mch_id", redisService.getString(ConstantsValue.WX_COFIG + "MCH_ID"));//商户号
        data.put("nonce_str", WXPayUtil.generateUUID());//随机字符串
        data.put("body", body);//商品描述
        data.put("out_trade_no", orderNum);//商户订单号
        data.put("total_fee", String.valueOf(totalFee.intValue()));//标价金额
        data.put("spbill_create_ip", ConstantsValue.CLIENT_IP);//终端IP
        data.put("notify_url", redisService.getString(ConstantsValue.WX_COFIG + "WX_NOTIFY"));//通知地址
        data.put("trade_type", ConstantsValue.TRADE_TYPE);//交易类型
        data.put("openid", userEntity.getOpenId());//用户登陆时的openid
        data.put("attach", type);


        //生成订单记录
        WxPayOrderlEntity wxPayOrderlEntity = new WxPayOrderlEntity();
        wxPayOrderlEntity.setAppid(redisService.getString(ConstantsValue.WX_COFIG + "WX_APPID"));
        wxPayOrderlEntity.setMchId(redisService.getString(ConstantsValue.WX_COFIG + "MCH_ID"));
        wxPayOrderlEntity.setBody(body);
        wxPayOrderlEntity.setOutTradeNo(orderNum);
        wxPayOrderlEntity.setTotalFee(someValEntity.getValue1());
        wxPayOrderlEntity.setOpenid(userEntity.getOpenId());
        wxPayOrderlEntity.setAttach(type);
        wxPayOrderlEntity.setCreateTime(new Timestamp(System.currentTimeMillis()));
        wxPayOrderlEntity.setModifyTime(new Timestamp(System.currentTimeMillis()));
        wxPayOrderlEntity.setStatus(ConstantsValue.STATUS_NO_DEL);
        wxPayOrderMapper.insert(wxPayOrderlEntity);


        //请求微信“统一下单”接口
        Map<String, String> res = new HashMap<>();
        res.put("appId", redisService.getString(ConstantsValue.WX_COFIG + "WX_APPID"));
        res.put("timeStamp", String.valueOf(System.currentTimeMillis()));
        res.put("nonceStr", WXPayUtil.generateUUID());
        res.put("signType", ConstantsValue.SIGN_TYPE);

        try {

            WXPay wxpay = new WXPay(new MyConfig(redisService.getString(ConstantsValue.WX_COFIG + "WX_APPID"),redisService.getString(ConstantsValue.WX_COFIG + "MCH_ID"),redisService.getString(ConstantsValue.WX_COFIG + "MCH_KEY")));
            Map<String, String> resp = wxpay.unifiedOrder(data);

            if (ConstantsValue.FAIL.equals(resp.get("return_code"))){
                throw new ApiException(ErrorCodeEnum.WX1);
            }
            if (ConstantsValue.FAIL.equals(resp.get("result_code"))){
                throw new ApiException(ErrorCodeEnum.WP8010);
            }

            res.put("package","prepay_id="+resp.get("prepay_id"));
            String paySign = WXPayUtil.generateSignature(res,redisService.getString(ConstantsValue.WX_COFIG + "MCH_KEY"));
            res.put("paySign",paySign);
            JSONObject json = JSONObject.parseObject(JSON.toJSONString(res));
            return ResponseWrapper.succeed(json);
        } catch (Exception e) {
            throw new ApiException(ErrorCodeEnum.WP8010);
        }
    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper reportList(Integer page, Integer limit, Integer isReally, String userName) {
        Example example=new Example(ReportEntity.class);
        example.setOrderByClause("report_id desc");

        Example.Criteria criteria = example.createCriteria();
        if(isReally != null)
            criteria.andEqualTo("isReally", isReally);
        if(StringUtils.isNotBlank(userName))
            criteria.andLike("reportUserName", "%"+userName+"%");

        RowBounds rowBounds = RowBoundUtil.getRowBounds(limit, page);
        List<ReportEntity> reportEntityList = reportsMapper.selectByExampleAndRowBounds(example, rowBounds);

        int count = reportsMapper.selectCountByExample(example);

        return ResponseWrapper.succeed(count, reportEntityList);
    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper examineReport(Integer id, Integer isReally) {
        ReportEntity reportEntity = new ReportEntity();
        reportEntity.setReportId(id);

        reportEntity = reportsMapper.selectOne(reportEntity);
        reportEntity.setIsReally(isReally);
        reportsMapper.updateByPrimaryKey(reportEntity);

        return ResponseWrapper.succeed();
    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper payList(Integer page, Integer limit, String resultCode, String errCode, String outTradeNo, Integer attach, String transactionId) {

        Example example=new Example(WxPayOrderlEntity.class);
        example.setOrderByClause("id desc");

        Example.Criteria criteria = example.createCriteria();
        if(StringUtils.isNotBlank(resultCode))
            criteria.andEqualTo("resultCode", resultCode);
        if(StringUtils.isNotBlank(errCode))
            criteria.andEqualTo("errCode", errCode);
        if(StringUtils.isNotBlank(outTradeNo))
            criteria.andEqualTo("outTradeNo", outTradeNo);
        if(attach != null)
            criteria.andEqualTo("attach", attach);
        if(StringUtils.isNotBlank(transactionId))
            criteria.andEqualTo("transactionId", transactionId);

        RowBounds rowBounds = RowBoundUtil.getRowBounds(limit, page);
        List<WxPayOrderlEntity> wxPayOrderlEntityList = wxPayOrderMapper.selectByExampleAndRowBounds(example, rowBounds);

        int count = wxPayOrderMapper.selectCountByExample(example);

        return ResponseWrapper.succeed(count, wxPayOrderlEntityList);
    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper transferList(Integer page, Integer limit, String resultCode, String parterTradeNo, String errCode, String paymentNo, String reUserName) {

        Example example=new Example(WxTransferPayEntity.class);
        example.setOrderByClause("id desc");

        Example.Criteria criteria = example.createCriteria();
        if(StringUtils.isNotBlank(resultCode))
            criteria.andEqualTo("resultCode", resultCode);
        if(StringUtils.isNotBlank(parterTradeNo))
            criteria.andEqualTo("parterTradeNo", parterTradeNo);
        if(StringUtils.isNotBlank(errCode))
            criteria.andEqualTo("errCode", errCode);
        if(StringUtils.isNotBlank(paymentNo))
            criteria.andEqualTo("paymentNo", paymentNo);
        if(StringUtils.isNotBlank(reUserName))
            criteria.andEqualTo("reUserName", reUserName);

        RowBounds rowBounds = RowBoundUtil.getRowBounds(limit, page);

        List<WxTransferPayEntity> wxTransferPayEntityList = wxTransferPayMapper.selectByExampleAndRowBounds(example, rowBounds);

        int count = wxTransferPayMapper.selectCountByExample(example);

        return ResponseWrapper.succeed(count, wxTransferPayEntityList);

    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper reDrawn(String outTradeNo) {
        WxTransferPayEntity wxTransferPayEntity = new WxTransferPayEntity();
        wxTransferPayEntity.setPartnerTradeNo(outTradeNo);
        wxTransferPayEntity = wxTransferPayMapper.selectOne(wxTransferPayEntity);

        if (wxTransferPayEntity == null){
            throw new ApiException(ErrorCodeEnum.WP8018);
        }

        Map<String, String> res = new HashMap<>();
        res.put("mch_appid", wxTransferPayEntity.getMchAppid());//商户账号appid
        res.put("mchid", wxTransferPayEntity.getMchid());//商户号
        res.put("nonce_str",wxTransferPayEntity.getNonceStr());//随机字符串
        res.put("partner_trade_no", wxTransferPayEntity.getPartnerTradeNo());//商户订单号,务必使用原来的商户订单号
        res.put("openid", wxTransferPayEntity.getOpenid());//用户openid
        res.put("check_name", wxTransferPayEntity.getCheckName());//校验用户姓名选项
        res.put("re_user_name", wxTransferPayEntity.getReUserName());//收款用户姓名
        res.put("amount", wxTransferPayEntity.getAmount());//金额
        res.put("desc", wxTransferPayEntity.getRemarkDesc());//企业付款备注


        if (ConstantsValue.SUCCESS.equals(wxTransferPayEntity.getResultCode())){
            throw new ApiException(ErrorCodeEnum.WP8019);
        }
        //下面这些err_code 务必使用原商户订单号重新申请提现
        if ("NOTENOUGH".equals(wxTransferPayEntity.getErrCode())
                || "SYSTEMERROR".equals(wxTransferPayEntity.getErrCode())
                || "NAME_MISMATCH".equals(wxTransferPayEntity.getErrCode())
                || "SIGN_ERROR".equals(wxTransferPayEntity.getErrCode())
                || "FREQ_LIMIT".equals(wxTransferPayEntity.getErrCode())
                || "MONEY_LIMIT".equals(wxTransferPayEntity.getErrCode())
                || "CA_ERROR".equals(wxTransferPayEntity.getErrCode())
                || "V2_ACCOUNT_SIMPLE_BAN".equals(wxTransferPayEntity.getErrCode())
                || "PARAM_IS_NOT_UTF8".equals(wxTransferPayEntity.getErrCode())
                || "SENDNUM_LIMIT".equals(wxTransferPayEntity.getErrCode())){

            Map<String, String> resp = new HashMap<>();
            try {
                String paySign = WXPayUtil.generateSignature(res, redisService.getString(ConstantsValue.WX_COFIG + "MCH_KEY"));
                res.put("sign",paySign);
                WXPay wxpay = new WXPay(new MyConfig(redisService.getString(ConstantsValue.WX_COFIG + "WX_APPID"),redisService.getString(ConstantsValue.WX_COFIG + "MCH_ID"),redisService.getString(ConstantsValue.WX_COFIG + "MCH_KEY")));
                wxpay.transfers(res);//企业付款接口
                wxTransferPayEntity.setReturnCode(resp.get("return_code"));
                wxTransferPayEntity.setReturnMsg(resp.get("return_msg"));
            } catch (Exception e) {
                throw new ApiException(ErrorCodeEnum.WP8016);
            }
            if (ConstantsValue.FAIL.equals(resp.get("return_code"))){//通信失败
                throw new ApiException(ErrorCodeEnum.WX1);
            }else{
                //return_code 为success 时有返回下列字段
                wxTransferPayEntity.setResultCode(resp.get("result_code"));
                wxTransferPayEntity.setErrCode(resp.get("err_code"));
                wxTransferPayEntity.setErrCodeDes(resp.get("err_code_des"));
                if (ConstantsValue.FAIL.equals(resp.get("result_code"))){//通信成功，业务失败
                    //以下errcode ，系统务必使用原来的商户订单号重试提现操作
                    if ("NOTENOUGH".equals(wxTransferPayEntity.getErrCode())
                            || "SYSTEMERROR".equals(wxTransferPayEntity.getErrCode())
                            || "NAME_MISMATCH".equals(wxTransferPayEntity.getErrCode())
                            || "SIGN_ERROR".equals(wxTransferPayEntity.getErrCode())
                            || "FREQ_LIMIT".equals(wxTransferPayEntity.getErrCode())
                            || "MONEY_LIMIT".equals(wxTransferPayEntity.getErrCode())
                            || "CA_ERROR".equals(wxTransferPayEntity.getErrCode())
                            || "V2_ACCOUNT_SIMPLE_BAN".equals(wxTransferPayEntity.getErrCode())
                            || "PARAM_IS_NOT_UTF8".equals(wxTransferPayEntity.getErrCode())
                            || "SENDNUM_LIMIT".equals(wxTransferPayEntity.getErrCode())){
                        return ResponseWrapper.failed(ErrorCodeEnum.WP8015);

                    }else if ("SEND_FAILED".equals(wxTransferPayEntity.getErrCode())){//付款错误，请查单确认付款结果
                        return ResponseWrapper.failed(ErrorCodeEnum.WP8022);
                    }else{//其他原因直接回退
                        throw new ApiException(ErrorCodeEnum.WP8021);
                    }
                }else{
                    //result_code 为success 时有返回下列字段
                    wxTransferPayEntity.setPaymentNo(resp.get("payment_no"));
                    wxTransferPayEntity.setPaymentTime(resp.get("payment_time"));
                }
                wxTransferPayMapper.updateByPrimaryKey(wxTransferPayEntity);

                return ResponseWrapper.succeed();//提现成功
            }

        }else{//其他err_code 请对照文档处理
            throw new ApiException(ErrorCodeEnum.WP8020);
        }


    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper closeOrOpen() {

        SomeValEntity someValEntity = new SomeValEntity();
        someValEntity.setKey1("co");
        someValEntity = someValMapper.selectOne(someValEntity);
        Integer co = Integer.valueOf(someValEntity.getValue1());
        someValEntity.setValue1(String.valueOf(co == ConstantsValue.OPEN_CO ? ConstantsValue.CLOSE_CO : ConstantsValue.OPEN_CO));
        someValMapper.updateByPrimaryKey(someValEntity);
        return ResponseWrapper.succeed(someValEntity.getValue1());
    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper getCO() {

        SomeValEntity someValEntity = new SomeValEntity();
        someValEntity.setKey1("co");
        someValEntity = someValMapper.selectOne(someValEntity);
        return ResponseWrapper.succeed(someValEntity.getValue1());
    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper uploadIdCard(MultipartFile file, Integer userId) {
        UserEntity userEntity = new UserEntity();
        userEntity.setUserId(userId);
        userEntity = userMapper.selectOne(userEntity);
        if (userEntity.getAuthStatus() == ConstantsValue.AUTH_OK){
            throw new ApiException(ErrorCodeEnum.TK1017);
        }

        //2.根据时间戳创建新的文件名，这样即便是第二次上传相同名称的文件，也不会把第一次的文件覆盖了
        String fileName = System.currentTimeMillis() + file.getOriginalFilename();
        //3.通过req.getServletContext().getRealPath("") 获取当前项目的真实路径，然后拼接前面的文件名
//            String destFileName = req.getServletContext().getRealPath("") + "uploaded" + File.separator + fileName;

        if(ConstantsValue.isWindows){
            String path = "myimg" + File.separator + fileName;
            String destFileName = File.listRoots()[0].getAbsolutePath() + path;
            //4.第一次运行的时候，这个文件所在的目录往往是不存在的，这里需要创建一下目录（创建到了webapp下uploaded文件夹下）
            File destFile = new File(destFileName);
            destFile.getParentFile().mkdirs();
            //5.把浏览器上传的文件复制到希望的位置
            try {
                file.transferTo(destFile);
            } catch (IOException e) {
                e.printStackTrace();
            }
            //6.把文件名放在model里，以便后续显示用
//            m.addAttribute("fileName", fileName);
//                String url = request.getScheme()+"://"+ request.getServerName() + ":" + request.getServerPort() + "/";
            String filePath = ConstantsValue.FACK_ADD + "myimg/" + fileName;
            log.info("图片访问路径 :{}", filePath);
            SimpleUploadFileDemo.SimpleUploadFileFromLocal("myimg/"+fileName, "C:/"+path, false);

            createApplyAuth(filePath, userId);


            return ResponseWrapper.succeed(filePath);
        }else{
            String path = "/myimg" + File.separator + fileName;
            //4.第一次运行的时候，这个文件所在的目录往往是不存在的，这里需要创建一下目录（创建到了webapp下uploaded文件夹下）
            File destFile = new File(path);
            destFile.getParentFile().mkdirs();
            //5.把浏览器上传的文件复制到希望的位置
            try {
                file.transferTo(destFile);
            } catch (IOException e) {
                e.printStackTrace();
            }
            //6.把文件名放在model里，以便后续显示用
//            m.addAttribute("fileName", fileName);
//                String url = request.getScheme()+"://"+ request.getServerName() + ":" + request.getServerPort() + "/";
            String filePath = ConstantsValue.FACK_ADD + "myimg/" + fileName;
            log.info("图片访问路径 :{}", filePath);

            SimpleUploadFileDemo.SimpleUploadFileFromLocal("myimg/"+fileName, path, false);

            createApplyAuth(filePath, userId);
            return ResponseWrapper.succeed(filePath);
        }
    }

    /**
     * 获取敏感功能状态
     *
     * @return
     */
    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper loadData() {
        SomeValEntity someValEntity = new SomeValEntity();
        someValEntity.setKey1("co");
        return ResponseWrapper.succeed(someValMapper.selectOne(someValEntity).getValue1());
    }

    @Transactional(propagation=Propagation.REQUIRED)
    @Override
    public ResponseWrapper uploadPicture(MultipartFile file) {

        //2.根据时间戳创建新的文件名，这样即便是第二次上传相同名称的文件，也不会把第一次的文件覆盖了
        String fileName = System.currentTimeMillis() + file.getOriginalFilename();
        //3.通过req.getServletContext().getRealPath("") 获取当前项目的真实路径，然后拼接前面的文件名
//            String destFileName = req.getServletContext().getRealPath("") + "uploaded" + File.separator + fileName;

        if(ConstantsValue.isWindows){
            String path = "myimg" + File.separator + fileName;
            String destFileName = File.listRoots()[0].getAbsolutePath() + path;
            //4.第一次运行的时候，这个文件所在的目录往往是不存在的，这里需要创建一下目录（创建到了webapp下uploaded文件夹下）
            File destFile = new File(destFileName);
            destFile.getParentFile().mkdirs();
            //5.把浏览器上传的文件复制到希望的位置
            try {
                file.transferTo(destFile);
            } catch (IOException e) {
                e.printStackTrace();
            }
            //6.把文件名放在model里，以便后续显示用
//            m.addAttribute("fileName", fileName);
//                String url = request.getScheme()+"://"+ request.getServerName() + ":" + request.getServerPort() + "/";
            String filePath = ConstantsValue.FACK_ADD + "myimg/" + fileName;
            log.info("图片访问路径 :{}", filePath);

            SimpleUploadFileDemo.SimpleUploadFileFromLocal("myimg/"+fileName, "C:/"+path, false);
            return ResponseWrapper.succeed(filePath);
        }else{
            String path = "/myimg" + File.separator + fileName;
            //4.第一次运行的时候，这个文件所在的目录往往是不存在的，这里需要创建一下目录（创建到了webapp下uploaded文件夹下）
            File destFile = new File(path);
            destFile.getParentFile().mkdirs();
            //5.把浏览器上传的文件复制到希望的位置
            try {
                file.transferTo(destFile);
            } catch (IOException e) {
                e.printStackTrace();
            }
            //6.把文件名放在model里，以便后续显示用
//            m.addAttribute("fileName", fileName);
//                String url = request.getScheme()+"://"+ request.getServerName() + ":" + request.getServerPort() + "/";
            String filePath = ConstantsValue.FACK_ADD + "myimg/" + fileName;
            log.info("图片访问路径 :{}", filePath);

            SimpleUploadFileDemo.SimpleUploadFileFromLocal("myimg/"+fileName, path, false);
            return ResponseWrapper.succeed(filePath);


        }
    }


    private void createApplyAuth(String filePath, Integer userId){
        String cardA = filePath;
        String jsonStr = GeneralAccurateOCR.parseImage(cardA);
        JSONArray jsons = JSONObject.parseObject(jsonStr).getJSONArray("TextDetections");
        ApplyAuthEntity applyAuthEntity = new ApplyAuthEntity();
        applyAuthEntity.setUserId(userId);
        applyAuthEntity = applyAuthMapper.selectOne(applyAuthEntity);
        int hasObject = 0;
        if (applyAuthEntity == null){
            applyAuthEntity = new ApplyAuthEntity();
            applyAuthEntity.setUserId(userId);
            applyAuthEntity.setCreateTime(new Timestamp(new Date().getTime()));
            hasObject = 1;
        }
        applyAuthEntity.setIsExamina(ConstantsValue.NO_EXAMINE);
        applyAuthEntity.setHead("");
        applyAuthEntity.setCardA(cardA);
        applyAuthEntity.setCardB("");
        applyAuthEntity.setStatus(ConstantsValue.STATUS_NO_DEL);

        for (int i=0;i<jsons.size();i++){
            String str = jsons.getJSONObject(i).getString("DetectedText");
            if (str.contains("姓名") && "姓名".equals(str.substring(0,2))){
                applyAuthEntity.setRealName(str.replace("姓名", "").trim());
            }else if (str.contains("性别") && str.contains("民族") && "性别".equals(str.substring(0,2)) ){
                str = str.replace("性别","").replace("民族","-").trim();
                String s[] = str.split("-");
                applyAuthEntity.setSex(s[0]);
                applyAuthEntity.setNation(s[1]);
            }else if (str.contains("性别") && "性别".equals(str.substring(0,2)) ){
                str = str.replace("性别","").trim();
                applyAuthEntity.setSex(str);
            }else if (str.contains("民族") && "民族".equals(str.substring(0,2)) ){
                str = str.replace("民族","").trim();
                applyAuthEntity.setNation(str);
            }else if (str.contains("出生") && str.contains("年") && str.contains("月") && str.contains("日")){
                str = str.replace("出生","").replace("年","-").replace("月","-").replace("日","-").trim();
                String s[] = str.split("-");
                applyAuthEntity.setYear(s[0]);
                applyAuthEntity.setMouth(s[1]);
                applyAuthEntity.setDay(s[2]);
            }else if (str.contains("住址") && "住址".equals(str.substring(0,2))){
                applyAuthEntity.setAddr(str.replace("住址","").trim());
            }else if (str.contains("公民身份号码") && "公民身份号码".equals(str.substring(0,6))){
                applyAuthEntity.setIdCard(str.replace("公民身份号码","").trim());
            }else if (str.contains("中国CHINA") && "中国CHINA".equals(str)){
                System.out.println(str);
            }else {
                applyAuthEntity.setAddr(applyAuthEntity.getAddr().concat(str.trim()));
            }
        }

        if (hasObject == 0){
            applyAuthMapper.updateByPrimaryKey(applyAuthEntity);
        }else{
            applyAuthMapper.insert(applyAuthEntity);
        }
    }
}
